#! /bin/sh
#
# Simple script to try out each probe in turn so we can 
# know where we may die. Allow me to manually try things out
# as we update the cpu_emulate.c code
#
# Following is just a scratch pad of issues I am working on. All
# of them are fine, except, usually, the last one.
#
# Dies at ipt_local_out_hook entry in 
# Linux vmub32 2.6.24-16-generic #1 SMP Thu Apr 10 13:23:42 UTC 2008 i686 GNU/Linux
# 0x00000030 <ipt_local_out_hook+0>:      sub    $0xc,%esp
# This frame is too small - so cpu_emulate.c will fail.
#
# /lib/modules/2.6.24-16-generic/kernel/net/ipv4/netfilter/iptable_filter.ko
# ipt_hook
# 0xb0 <ipt_hook>:        push   %ebx    // 53
#
# *** entry-patchpoint: ata_qc_issue_prot
# ipt_local_out_hook

# dev_hard_start_xmit
# dtrace -n fbt::ext3_file_write:

entry=0
skip=-0
type=fbt

while [ "$1" != "" ]
do
	case "$1" in 
	  [0-9]*)
		entry=$1
		shift
		;;
	  -fbt)
		type=fbt
		shift
		;;
	  -find)
		name=$2
		find  /lib/modules/`uname -r`/ -name \*.ko | 
		while read mod
		do
			nm $mod | grep $name >/dev/null && 
			(echo $mod ; nm $mod | grep $name)
		done
		exit
		;;
	  -invop)
		invop=$2
		grep invop=$invop /var/log/messages | sed -e 's/^.*:alloc //' |sort |
		while read type func addr invop
		do
			echo "*** $type $func"
			dtrace -n "fbt::$func:  { @[probefunc] = count(); }
				profile:::tick-1sec { exit(0); }
				"
		done
		exit
		;;
	  -skip)
		skip=-$2
		entry=$2
		shift ; shift
		;;
	  -syscall)
		type=syscall
		shift
		;;
	  -help)
		cat <<EOF
Script to help validate and regression test dtrace for Linux.
It provides mechanisms to automate trying out each probe individually
to isolate probes which can panic the kernel.

Switches:

  -fbt                  Iterate through each fbt function.
  -find name            Find the kernel module containing a function
  -invop NN             Look at /var/log/messages for functions which match
                        specific invop cases where we need to emulate the
			missing instructions.
  -syscall              Iterate each syscall in turn.
  -skip NN              When iterating over syscalls/fbt, start from this
                        sequence, e.g. to continue after aborting the script.
EOF
		exit
		;;
	esac
done

if [ "$1" != "" ]; then
	func=$1
	dtrace -n "$type::$func  { @[probefunc] = count(); }
		profile:::tick-1sec { exit(0); }
		"
	exit
fi

grep $type.*entry /tmp/probes.current | 
head --lines=$skip |
while read id provider module func startstop
do
	if [ "$type" = "syscall" ]; then
		startstop=$func
		func=$module
	fi
	echo "*** Entry $entry: $func $startstop"
	dtrace -n "$type::$func:entry  { @[probefunc] = count(); }
		profile:::tick-250msec { exit(0); }
		"
	entry=`expr $entry + 1`
done

## New processes with arguments,
#dtrace -n 'proc:::exec-success { trace(curpsinfo->pr_psargs); }'
# 
## Files opened by process,
#dtrace -n 'syscall::open*:entry { printf("%s %s",execname,copyinstr(arg0)); }'
# 
## Syscall count by program,
#dtrace -n 'syscall:::entry { @num[execname] = count(); }'
# 
## Syscall count by syscall,
#dtrace -n 'syscall:::entry { @num[probefunc] = count(); }'
# 
## Syscall count by process,
#dtrace -n 'syscall:::entry { @num[pid,execname] = count(); }'
# 
## Disk size by process,
#dtrace -n 'io:::start { printf("%d %s %d",pid,execname,args[0]->b_bcount); }'   
# 
## Pages paged in by process,
#dtrace -n 'vminfo:::pgpgin { @pg[execname] = sum(arg0); }'

